SIGILL(Illegal instruction)问题定位

  1. 1、问题描述
  2. 2、问题原因
    1. 2.1、错误修改代码段
    2. 2.2、指令集演进
    3. 2.3 工具链Bug
    4. 2.4、内存访问对齐或浮点格式问题
  3. 3、错误排查指南
  4. 4、示例分析

1、问题描述

进程在运行过程中会收到SIGILL信号,此类错误是由操作系统发送给进程的。

SIGILL是某个进程中的某一句不能被CPU识别指令,这些指令可能是一些形式错误、未知或者特权指令。

2、问题原因

2.1、错误修改代码段

进程代码段中数据是作为指令运行的,如果不小心代码段被错误覆盖,那么CPU可能无法识别对应的代码,进而造成Illegal Instruction。

同样,如果栈被不小心覆盖了,造成返回地址错误、CPU跳转到错误地址,执行没有意义的内存数据,进而造成Illegal Instruction。

进一步可以认为,任何导致代码段错误的问题都可能带来Illegal Instruction。

2.2、指令集演进

CPU的指令集在不停演进,如果将较新指令集版本的程序在老版本CPU上运行,则老版本CPU运行时会有Illegal Instruction问题。

2.3 工具链Bug

编译器(汇编器或者连接器)自身的bug,有可能生成CPU无法识别的指令。

2.4、内存访问对齐或浮点格式问题

出现错误的指令可能和访存地址指令有关。 另外,浮点数的格式是否符合IEEE的标准也可能会有影响。

3、错误排查指南

  • 程序中有没有特权指令、或者访问特权寄存器

  • 有没有将在较新CPU上编译得到的可执行文件拿到老CPU上运行————这种问题是100%复现,只需要查看对应汇编程序即可知道大概。

  • 程序中有没有嵌入式汇编,先检查。————————————————-编译器bug。

  • 一般编译器很少会生成有这种问题的代码

  • X86平台上要尤其注意64位汇编指令和32位汇编指令的混用问题

  • 程序有在进程代码段空间写数据的机会吗?—————————————-下面的分析就是代码段被非法修改。还可能是意见存在问题,DDR中数据正确,从DDR读取的数据经过总线产生数据突变异常。

  • 栈操作够安全吗?————————————————————————–如果异常PC指向栈,那么即是栈被非法修改。

  • 注意程序的ABI是否正确——————————————————————100%复现问题,只需要检查ABI说明书即可。
    尤其是动态链和静态链是否处理的正确,尽量避免动态链的可执行文件调用错误库的问题(ARM的EABI,MIPS的N32/O32/N64都很可能出这种问题)

  • 用的工具链靠谱吗?

4、示例分析

在这里插入图片描述
上述问题是由于升级GCC版本(进一步分析其实是使用的龙芯机器上没有开启MSA特性导致)导致编译器转换成汇编代码时转换错误,导致CPU不识别对应指令报错。


THE END!


本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com

文章标题:SIGILL(Illegal instruction)问题定位

字数:801

本文作者:Soaring Lee

发布时间:2021-10-25, 20:07:17

最后更新:2021-10-27, 22:47:39

原始链接:https://soaringleefighting.github.io/2021/10/25/【Debug系列】SIGILL(Illegal instruction)问题定位/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏

相册